package cn.com.taiji.core;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.generator.BaseModelGenerator;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;

import cn.hutool.core.date.DateUtil;

/**
 * @author dongwei dongweia@mail.taiji.com.cn
 */
public class CommonGenTemplate extends BaseModelGenerator {
    private String baseModelPackageNamemy;
    private String baseTargetProject;
    private String suffix;
    private String fileType = ".java";
    private String modelName = null;

    private String mpackage;

    public CommonGenTemplate(String modelPackageNamearg, String modelOutputDirarg, String suffix) {
        super(modelPackageNamearg, modelOutputDirarg);
        this.baseModelPackageNamemy = modelPackageNamearg;
        this.baseTargetProject = modelOutputDirarg;
        this.suffix = suffix;
    }

    public CommonGenTemplate(String modelOutputDirarg, String suffix, String fileType, String modelName) {
        super("jsp", modelOutputDirarg);
        this.baseTargetProject = modelOutputDirarg;
        this.suffix = suffix;
        this.fileType = fileType;
        this.modelName = modelName;
    }

    /**
     * base model 覆盖写入
     */
    @Override
    protected void writeToFile(TableMeta tableMeta) throws IOException {
        File dir = new File(baseModelOutputDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String target = null;
        if (getFileType().equals(".jsp")) {
            target = baseModelOutputDir + File.separator + modelName + getFileType();
        } else {
            target = baseModelOutputDir + File.separator + tableMeta.baseModelName + getFileType();
        }

        File file = new File(target);
        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        file.createNewFile();

        FileWriter fw = new FileWriter(target);
        try {
            fw.write(tableMeta.baseModelContent);
        } finally {
            fw.close();
            System.out.println("文件生成到:" + file.getAbsolutePath());
        }
    }

    @Override
    protected void genBaseModelContent(TableMeta tableMeta) {
        Kv data = Kv.by("baseModelPackageName", baseModelPackageName);
        data.set("generateChainSetter", generateChainSetter);
        data.set("tableMeta", tableMeta);
        data.set("dateMake", DateUtil.now());
        data.set("mpackage", mpackage);
        //engine.addSharedObject("dateMake", DateUtil.now());

        tableMeta.baseModelContent = engine.getTemplate(template).renderToString(data);
    }

    /**
     * 重写数据填充方法
     *
     * @param tableMetas
     */
    @Override
    public void generate(List<TableMeta> tableMetas) {
        Engine engine = Engine.create("forBaseModel");
        engine.setSourceFactory(new ClassPathSourceFactory());
        engine.addSharedMethod(new StrKit());
        engine.addSharedObject("getterTypeMap", getterTypeMap);
        engine.addSharedObject("javaKeyword", javaKeyword);

        for (TableMeta tableMeta : tableMetas) {
            this.genBaseModelContent(tableMeta);
        }
        for (TableMeta tableMeta : tableMetas) {
            tableMeta.baseModelName = tableMeta.modelName + suffix;
        }
        this.writeToFile(tableMetas);
        Engine.remove("forBaseModel");
    }

    public void generate(List<TableMeta> tableMetas, String mpackage) {
        this.mpackage = mpackage;
        this.generate(tableMetas);
    }

    public String getBaseModelPackageNamemy() {
        return baseModelPackageNamemy;
    }

    public void setBaseModelPackageNamemy(String baseModelPackageNamemy) {
        this.baseModelPackageNamemy = baseModelPackageNamemy;
    }

    public String getBaseModelOutputDirmy() {
        return baseTargetProject;
    }

    public void setBaseModelOutputDirmy(String baseModelOutputDirmy) {
        this.baseTargetProject = baseModelOutputDirmy;
    }

    public String getFileType() {
        return fileType;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }
}
